home *** CD-ROM | disk | FTP | other *** search
- Path: news.salford.ac.uk!aber!not-for-mail
- From: pcg@aber.ac.uk (Piercarlo Grandi)
- Newsgroups: comp.object,comp.lang.eiffel,comp.lang.c++,comp.lang.beta,comp.lang.java,comp.lang.sather
- Subject: Re: What Should An Exception Handling Do? -- Clarification of rules
- Date: 09 Apr 1996 19:34:02 +0100
- Organization: Prifysgol Cymru, Aberystwyth
- Sender: pcg@osfb.aber.ac.uk
- Message-ID: <vwjk9zpckmd.fsf@osfb.aber.ac.uk>
- References: <4irn11$7ln@mimas.brunel.ac.uk> <4j03p4$fbt@hoho.quake.net>
- <Doq3sv.MzA@research.att.com> <vwjg2ao6hqp.fsf@osfb.aber.ac.uk>
- <4jqjvg$d9@glympton.airtime.co.uk>
- Reply-To: pcg@aber.ac.uk (Piercarlo Grandi)
- NNTP-Posting-Host: osfb.aber.ac.uk
- In-reply-to: wysiwyg@glympton.airtime.co.uk's message of 2 Apr 1996 08:11:44 +0100
- X-Newsreader: Gnus v5.0.15
-
- >>> On 2 Apr 1996 08:11:44 +0100, wysiwyg@glympton.airtime.co.uk (Adam L
- >>> Rice) said:
-
- pcg> The exception facility of e.g. C++ is merely a (rather ad-hoc and
- pcg> opaque) way of allowing the definition of what are in effect
- pcg> dynamically scoped procedure names, forcibly coupled with non-local
- pcg> control transfer.
-
- wysiwyg> So, let me see if I've understood. What you're basically saying
- wysiwyg> is that instead of doing (in Java):
-
- wysiwyg> try {
- wysiwyg> sock = new Socket("wallawalla.mit.edu", 3456);
- wysiwyg> } catch (IOException e) {
- wysiwyg> ... // handle the exception
- wysiwyg> }
- wysiwyg> ... // use the socket
-
- wysiwyg> we should do something like:
-
- wysiwyg> if (Socket.ConnectWillWork("wallawalla.mit.edu", 3456) {
- wysiwyg> sock = new Socket("wallawalla.mit.edu", 3456);
- wysiwyg> ... // use the socket
- wysiwyg> } else {
- wysiwyg> ... // handle the exception
- wysiwyg> }
-
- wysiwyg> Hmmmm... that's a lovely code style! I think we can call this techique
- wysiwyg> 'APIx2', for obvious reasons.
-
- wysiwyg> But I'm not entirely clear, it might be you were saying we should do:
-
- wysiwyg> sock = new Socket("wallawalla.mit.edu", 3456, new CantConnectHandler());
- wysiwyg> if (!CantConnectHandler.ConnectFailed) {
- wysiwyg> ... // use the socket
- wysiwyg> }
-
- You are making all this up, and stupidly too, for neither of the
- examples you provide are anywhere similar to the ones I have given (for
- the ones I have given are examples of how things would look like at the
- place where the exception is *raised*, while your examples are about the
- place where it is *detected*), and neither exhibits dynamically scoped
- procedure names or non local control transfers, which are part of my
- definition. Amazing ability to misread! (and yes, I apologize if what I
- wrote was opaque, but I think I was darn well unambiguous).
-
- Perhaps you should reread more carefully what I have written, and
- perhaps refresh your memory on the notions of dynamic scoping and non
- local control transfer and how they look like.
-
- To help you see the light, here is your example:
-
- wysiwyg> try {
- wysiwyg> sock = new Socket("wallawalla.mit.edu", 3456);
- wysiwyg> } catch (IOException e) {
- wysiwyg> ... // handle the exception
- wysiwyg> }
- wysiwyg> ... // use the socket
-
- rewritten using something less ``ad hoc'' than 'try', and with dynamic
- scoping and non local control transfer as I had written:
-
- jmp_buf bailOutTo;
-
- static void localHandler(IOException e)
- {
- .... // handle the ``exception''
- longjmp(bailOutTo);
- }
-
- void try()
- {
- dynamic void (*IOExceptionHandler)(IOException) = localHandler;
-
- sock = new Socket("wallawalla.mit.edu", 3456);
- .... // use the socket
- }
-
- where presumably 'bailOutTo' is initialized to some recovery point
- somewhere.
-
- 'dynamic' would be new storage class, much like 'extern', but with
- dynamic scoping within blocks.
-
- The 'Socket' constructor would contain some bit of code like:
-
- dynamic void (*IOExceptionHandler)(IOException) = DefaultHandler;
-
- Socket::Socket(String s,int p)
- {
- ....
- if (nogood)
- {
- // we call the user's routine, equivalent to a 'raise'
- (*IOExceptionHandler)(new IOException(....));
- abort();
- }
- ....
- }
-
- Naturally one would write it a bit better, but I have written it this
- way to show the parallel between the 'try' construction and the more
- linear one based on dynamic scoping and non local control transfers.
-
- BTW, this style of ``exception handling'' has been rather the norm in
- Lisp/Scheme for the past few dozen years, and could be added to
- C++/Java/whatever in an afternoon (indeed 'dynamic' can be _simulated_
- tolerably well by a few lines of macros in C++).
-
- Dynamic scoping is useful BTW not just for providing ``exception
- handling'', but for a number of other uses, all those like ``exception
- handling'' where code semantics must depend on the dynamic context and
- not the static context, for example when there are runtime
- parameters. Currently this must be inelegantly simulated with idioms
- like:
-
- SomeType GlobalParameter = defaultValue;
-
- ....
-
- {
- SomeType savedGlobal = GlobalParameter;
- GlobalParameter = localValue;
-
- ....
-
- GlobalParameter = savedGlobal;
- }
-
- which if of course nothing but a manual (and hazardous) implementation
- of dynamic scoping for GlobalParameter, and that is seen rather often in
- C and C++ programs, instead of:
-
- SomeType Parameter = defaultValue;
- ....
-
- {
- dynamic SomeType Parameter = localValue;
-
- ....
- }
-
- BTW, I really hate ``exception handling'', for in cases like say 0/0
- there is not exception, jsut the inability to prescribe a particular
- semantics statically. I think that something like ``deferred semantics''
- would be a much more descriptive title.
-
- PS instead of 'dynamic' I think that 'extern auto' would be OK, and
- rather descriptive too, too bad that a C/C++ declaration can only have
- one storage class specifier.
-